package com.example.supplychainbackend.controller;

import com.example.supplychainbackend.controller.dto.enterprise.EnterpriseDto;
import com.example.supplychainbackend.controller.dto.user.RegisterRequestDto;
import com.example.supplychainbackend.service.EnterpriseService;
import com.example.supplychainbackend.tool.JwtUtil;
import com.example.supplychainbackend.controller.dto.DataResponse;
import com.example.supplychainbackend.controller.dto.user.LoginRequestDto;
import com.example.supplychainbackend.controller.dto.user.LoginResponseDto;
import com.example.supplychainbackend.controller.dto.user.UserInfoDto;
import com.example.supplychainbackend.dao.UserDao;
import com.example.supplychainbackend.entity.UserEntity;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;

@RestController
@AllArgsConstructor
@RequestMapping("api/sys")
public class UserController {
    private final UserDao userDao;
    private final EnterpriseService enterpriseService;

    @PostMapping("/login")
    public DataResponse<LoginResponseDto> login(@RequestBody LoginRequestDto dto) {
        UserEntity user = userDao.findByUsername(dto.getUsername());
        if (user == null){
            return new DataResponse<>(404,"username not found",null);
        }
        if (!user.getPassword().equals(dto.getPassword())){
            return new DataResponse<>(500,"wrong password",null);
        }

        EnterpriseDto enterpriseDto;
        if (null!= user.getEnterpriseId()){
            enterpriseDto = enterpriseService.getEnterprise(user.getEnterpriseId());
        } else {
            enterpriseDto = EnterpriseDto.builder().company("").id(0L).build();
        }

        String token = JwtUtil.generateToken(
                user.getUsername(),user.getId().toString(),
                enterpriseDto.getCompany(),enterpriseDto.getId().toString());

        LoginResponseDto responseDto = LoginResponseDto.builder().id(user.getId()).avatar(user.getAvatar())
                .username(user.getUsername())
                .token(token)
                .phone(user.getPhone())
                .enterpriseId(user.getEnterpriseId())
                .name(user.getName())
                .identity(user.getIdentity())
                .menus(Arrays.asList(user.getMenus().split(","))).build();
        return DataResponse.success(responseDto);
    }

    @PostMapping("/register")
    public DataResponse<Long> register(@RequestBody RegisterRequestDto dto) {
//        List<String> menus = Arrays.asList("design","enterprise","logistic","plan","production","project","purchase",
//                "quality","sales","supervise","trace","warehouse","user");

        UserEntity user = userDao.findByUsername(dto.getUsername());
        if (user != null){
            return new DataResponse<>(500,"duplicated username",null);
        }

        // filter sys menus
        UserEntity admin = userDao.findByUsername("admin");
        List<String> sysMenus;
        if (null == admin){
            sysMenus = Arrays.asList("design","enterprise","logistic","plan","production","project","purchase",
                    "quality","sales","supervise","trace","warehouse","user");
        }else {
            sysMenus = Arrays.asList(admin.getMenus().split(","));
        }
        List<String> userMenus = dto.getMenus();
        if (null == userMenus)
            userMenus = Arrays.asList("design","enterprise","logistic","plan","production","project","purchase",
                "quality","sales","supervise","trace","warehouse","user");

        userMenus.removeIf(module -> !sysMenus.contains(module));
        Long eId = dto.getEnterpriseId();
        if(eId == null){
            eId = enterpriseService.createEnterprise(EnterpriseDto.builder().build());
        }

        UserEntity userEntity = UserEntity.builder().username(dto.getUsername()).password(dto.getPassword())
        .menus(String.join(",",userMenus))
                .enterpriseId(eId)
                .identity(dto.getIdentity())
                .build();
        userEntity = userDao.save(userEntity);
        return DataResponse.success(userEntity.getId());
    }

    @GetMapping("/user/info")
    public DataResponse<UserInfoDto> getInfo(@RequestHeader("Authorization") String authHeader) {
        if (authHeader == null) {
            return new DataResponse<>(500,"Token missing or invalid format",null) ;
        }
        String token = authHeader;
        if (!JwtUtil.validateToken(token)) {
            return new DataResponse<>(401, "Invalid token",
                    null);
        }
        String name = JwtUtil.getUsernameFromToken(token);
        UserEntity user = userDao.findByUsername(name);
        if (user == null){
            return new DataResponse<>(500,"user "+name+" info not found",null);
        }
        UserInfoDto res = UserInfoDto.builder().id(user.getId()).avatar(user.getAvatar()).username(user.getUsername())
                .menus(Arrays.asList(user.getMenus().split(",")))
                .enterpriseId(user.getEnterpriseId())
                .identity(user.getIdentity())
                .name(user.getName()).phone(user.getPhone()).build();
        return DataResponse.success(res);
    }

//    @PostMapping("/user/info")
//    public DataResponse<UserInfoDto> editInfo(@RequestHeader("Authorization") String authHeader,
//                                              @RequestBody UserInfoDto info) {
//        if (authHeader == null || !authHeader.startsWith("Bearer ")) {
//            return new DataResponse<>(500,"Token missing or invalid format",null) ;
//        }
//        String token = authHeader.substring(7);
//        if (!JwtUtil.validateToken(token)) {
//            return new DataResponse<>(500, "Invalid token",
//                    null);
//        }
//        String name = JwtUtil.getUsernameFromToken(token);
//        UserEntity user = userDao.findByUsername(name);

    @PostMapping("/user/info/{id}")
    public DataResponse<UserInfoDto> editInfo(@PathVariable Long id,
                                              @RequestBody UserInfoDto info) {
        UserEntity user = userDao.findById(id).get();
//        if (user == null){
//            return new DataResponse<>(500,"user "+id+" info not found",null);
//        }
//        user.setUsername(info.getUsername());
        user.setAvatar(info.getAvatar());
//        user.setMenus(String.join(",",info.getMenus()));
        user.setPhone(info.getPhone());
        user.setName(info.getName());
        user = userDao.save(user);

        UserInfoDto res = UserInfoDto.builder()
                .id(user.getId())
                .avatar(user.getAvatar())
                .username(user.getUsername())
                .phone(user.getPhone())
                .name(user.getName())
                .enterpriseId(user.getEnterpriseId())
                .menus(Arrays.asList(user.getMenus().split(",")))
                .build();
        return DataResponse.success(res);
    }

    @GetMapping("/startup")
    public DataResponse<Boolean> systemStartupCheck() {
        if (0== userDao.count()){
            return DataResponse.success(false);
        }
        return DataResponse.success(true);
    }

    @PostMapping("/startup")
    public DataResponse<Long> systemStartup(@RequestBody RegisterRequestDto dto) {
        UserEntity user = userDao.findByUsername(dto.getUsername());
        if (user != null){
            return new DataResponse<>(500,"duplicated username",null);
        }
        Long eId = enterpriseService.createEnterprise(EnterpriseDto.builder()
                .company("系统管理员").build());

        UserEntity userEntity = UserEntity.builder().username(dto.getUsername()).password(dto.getPassword())
                .menus(String.join(",", dto.getMenus()))
                .identity(dto.getIdentity())
                .enterpriseId(eId).build();
        userEntity = userDao.save(userEntity);
        return DataResponse.success(userEntity.getId());
    }

    @GetMapping("/modules")
    public DataResponse<String> getConfiguredModules() {
        UserEntity admin = userDao.findByUsername("admin");
        return DataResponse.success(admin.getMenus());
    }

}